/*
 * Created on 8-April-2010
 *
 */

package be.ibridge.kettle.UpdateRRD;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.jrobin.core.RrdDb;
import org.jrobin.core.RrdDef;
import org.jrobin.core.RrdException;
import org.pentaho.di.core.Const;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDialogInterface;
import org.pentaho.di.ui.trans.step.BaseStepDialog;

public class UpdateRRDPluginDialog extends BaseStepDialog implements StepDialogInterface
{
	private UpdateRRDPluginMeta input;
	//private ValueMetaAndData value;

	static RrdDef rrdDef;
	static RrdDb rrdDb;
	
	static Table ArchiveTable;
	static String A_ArchiveTable[][];
	String StringArchiveTable;
	static TableItem item;
	private String RRDFile;
	
	private Label label0;
	private Text Text0;
	private Label label1;
	private Text Text1;
	private Label label2;
	private Combo combo, combo1, combo2;
	private Label label3;
	private Text Text3;
	private Label label4;
	private Text Text4;
	private Label label5;
	private Text Text5;
	private Label label6;
	private Text Text10;
	private Label label7;
	private Label label8;
	private Text Text8;
	private Text Text9;
	
	
	
	public UpdateRRDPluginDialog(Shell parent, Object in, TransMeta transMeta, String sname)
	{
		super(parent, (BaseStepMeta)in, transMeta, sname);
		input=(UpdateRRDPluginMeta)in;
	}

	public String open()
	{
		Shell parent = getParent();
		Display display = parent.getDisplay();
		
		shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX);
		shell.setSize(408, 520);
        setShellImage(shell, input);

		ModifyListener lsMod = new ModifyListener() 
		{
			public void modifyText(ModifyEvent e) 
			{
				input.setChanged();
			}
		};
		changed = input.hasChanged();

		FormLayout formLayout = new FormLayout ();
		formLayout.marginWidth  = Const.FORM_MARGIN;
		formLayout.marginHeight = Const.FORM_MARGIN;

		//shell.setLayout(formLayout);
		shell.setText(Messages.getString("UpdateRRDPluginDialog.Shell.Title")); //$NON-NLS-1$
		
		int middle = props.getMiddlePct();
		int margin = Const.MARGIN;
///////////////////////////////////////////////////////////////////////////////////
		//StepName
		wlStepname=new Label(shell, SWT.RIGHT);
		wlStepname.setText(Messages.getString("UpdateRRDPluginDialog.StepName.Label")); //$NON-NLS-1$
		wlStepname.setBounds(110,10,80,20);
		wStepname=new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wStepname.setText(stepname);
		wStepname.addModifyListener(lsMod);
		wStepname.setBounds(190,10,200,20);	
		//RRDFile 
		label0 = new Label (shell, SWT.NONE);
		label0.setText("RRD File :");
		label0.setBounds(140,40,50,20);
		Text0 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text0.addModifyListener(lsMod);
		Text0.setBounds(190,40,200,20);
		//RRDDatasource 
		label1 = new Label (shell, SWT.NONE);
		label1.setText("Datasource :");
		label1.setBounds(120,70,70,20);
		Text1 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text1.addModifyListener(lsMod);
		Text1.setBounds(190,70,200,20);
		// RRDTypeCombo
		label2 = new Label (shell, SWT.NONE);
		label2.setText("Type :");
		label2.setBounds(120,100,70,20);		
		combo = new Combo(shell, SWT.NULL);
		combo.setBounds(190,100,200,20);
	    String[] DST = new String[]{"COUNTER", "DERIVE", "ABSOLUTE", "GAUGE"};
	    for(int i=0; i<DST.length; i++)
	    combo.add(DST[i]);
		//RRDHeartBeat 
		label3 = new Label (shell, SWT.NONE);
		label3.setText("HeartBeat :");
		label3.setBounds(120,130,70,20);
		Text3 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text3.addModifyListener(lsMod);
		Text3.setBounds(190,130,200,20);
		//RRStarttime
		label6 = new Label (shell, SWT.NONE);
		label6.setText("Starttime :");
		label6.setBounds(120,175,70,20);
		Text10 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text10.setBounds(190,175,90,20);
		//Text10.setText("");  //920804400
		Text10.addModifyListener(lsMod);
		// Unix date management ....
		 // TimeStamp to date
		//final Date d = new Date(Long.parseLong(Text10.getText())*1000);
		//final SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		label7 = new Label (shell, SWT.RIGHT);
		label7.setBounds(190,200,85,20);
		//label7.setText(formatter.format(d));
		

		//Convert Epoch to Date Button
		Button EpochBut = new Button (shell, SWT.PUSH);
		EpochBut.setText ("&Epoch to date ->");
		EpochBut.setBounds(101, 200, 90, 20);
		EpochBut.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				final Date d = new Date(Long.parseLong(Text10.getText())*1000);
				final SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
				label7.setText(formatter.format(d));
			}
		});
	
		//RRDMin 
		label4 = new Label (shell, SWT.NONE);
		label4.setText("Min :");
		label4.setBounds(300,160,25,20);
		Text4 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text4.addModifyListener(lsMod);
		Text4.setBounds(340,160,50,20);
		//RRDMax 
		label5 = new Label (shell, SWT.NONE);
		label5.setText("Max :");
		label5.setBounds(300,190,25,20);
		Text5 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text5.addModifyListener(lsMod);
		Text5.setBounds(340,190,50,20);
		// RRDTypeCombo	
		combo1 = new Combo(shell, SWT.NULL);
		combo1.setBounds(10,230,130,20);
	    String[] CF = new String[]{"AVERAGE", "MIN", "MAX", "LAST"};
	    for(int i=0; i<CF.length; i++)
	    combo1.add(CF[i]);
	    // RRDXFileFactorCombo
		combo2 = new Combo(shell, SWT.NULL);
		combo2.setBounds(141,230,70,20);
	    String[] XFF = new String[]{"0","0.1","0.2","0.3","0.4","0.5","0.6","0.7","0.8","0.9","1"};
	    for(int i=0; i<XFF.length; i++)
	    combo2.add(XFF[i]);	    
		// NB of steps
		Text8 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text8.setText("Nb of steps");
		Text8.setBounds(212,230,70,20);
		Text8.addModifyListener(lsMod);
		// NB of rows
		Text9 = new Text (shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		Text9.setText("Nb of rows");
		Text9.setBounds(283,230,70,20);
		Text9.addModifyListener(lsMod);
		//ADDArchive_Button
		Button ADDArBut = new Button (shell, SWT.PUSH);
		ADDArBut.setText ("&Add");
		ADDArBut.setBounds(355, 225, 35, 30);
		ADDArBut.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if ((!Text8.getText().matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) || (!Text9.getText().matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")))
				{
					MessageBox messageBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
				    messageBox.setText("Warning");
				    messageBox.setMessage("You must type integers for STEPS and ROWS");
				    messageBox.open();
				    return;
				}
				else
				{
		        	item = new TableItem(ArchiveTable, SWT.NONE);
		        	item.setText(new String[] {combo1.getText(), combo2.getText(),Text8.getText(), Text9.getText() });
				}
			}
		});		
		
		//RRDARCHIVES
		ArchiveTable = new Table(shell, SWT.BORDER);
		ArchiveTable.setBounds(10, 260, 380, 160);
		ArchiveTable.setLinesVisible(true);
		ArchiveTable.setHeaderVisible(true);

	    TableColumn ConsolCol = new TableColumn(ArchiveTable, SWT.NONE);
	    ConsolCol.setText("Consol.");
	    ConsolCol.setWidth(130);
	    TableColumn xffCol = new TableColumn(ArchiveTable, SWT.NONE);
	    xffCol.setText("xff");
	    xffCol.setWidth(70);
	    TableColumn StepsCol = new TableColumn(ArchiveTable, SWT.NONE);
	    StepsCol.setText("Steps");
	    StepsCol.setWidth(70);
	    TableColumn RowsCol = new TableColumn(ArchiveTable, SWT.NONE);
	    RowsCol.setText("Rows");
	    RowsCol.setWidth(70);
		
	    // Label
		label8 = new Label (shell, SWT.NONE);
		label8.setText("Output command : ");
		label8.setBounds(10,420,400,20);
	    
		//OK Button
		Button OKBut = new Button (shell, SWT.PUSH);
		OKBut.setText ("&Ok");
		OKBut.setBounds(10, 450, 100, 30);
		OKBut.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ok();
			}
		});
		//CANCEL Button
		Button CancelBut = new Button (shell, SWT.PUSH);
		CancelBut.setText ("&Cancel");
		CancelBut.setBounds(230, 450, 100, 30);
		CancelBut.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				cancel();
			}
		});
		//VALIDATE Button
		Button ValiodateBut = new Button (shell, SWT.PUSH);
		ValiodateBut.setText ("&Validate and Create");
		ValiodateBut.setBounds(120, 450, 105, 30);
		ValiodateBut.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if ((ArchiveTable.getItemCount()==0) || (combo.getText().isEmpty()))
				{
					System.out.println(ArchiveTable.getItemCount());
					MessageBox messageBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
				    messageBox.setText("Warning");
				    messageBox.setMessage("You must choose one Type and add at least one Archive table");
				    messageBox.open();
				    return;
				}
				try {
					//Get Archive items and build an 2dim array with params
					//Build Archive strings
					BuildArchive();
					//Create RRD File with starttime converted from string to long
					String FxReturn = CreateRRDFile(Text0.getText(),Long.parseLong(Text10.getText()),Text1.getText(),combo.getText(),Long.parseLong(Text3.getText()),Double.parseDouble(Text4.getText()),Double.parseDouble(Text5.getText())  );
					label8.setText("The RRD file has been created with [" + FxReturn + "] as datasource");
				} catch (RrdException e1) {
					label8.setText("The RRD file [" + Text0.getText() +"] could not be created");
					e1.printStackTrace();
				} catch (IOException e1) {
					label8.setText("The RRD file [" + Text0.getText() +"] could not be created");
					e1.printStackTrace();
				} ;
			}
		});
		
		lsDef=new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent e) { ok(); } };
		wStepname.addSelectionListener( lsDef );
		
		shell.addShellListener(	new ShellAdapter() { public void shellClosed(ShellEvent e) { cancel(); } } );

		// Set the shell size, based upon previous time...
		//setSize();
		
		getData();
		input.setChanged(changed);
	
		shell.open();
		while (!shell.isDisposed())
		{
		    if (!display.readAndDispatch()) display.sleep();
		}
		return stepname;
	}

	protected void BuildArchive() {		
		StringArchiveTable = "";
		A_ArchiveTable = new String[ArchiveTable.getItemCount()][4];
		
		if(ArchiveTable.getItems().length<1) return;
		
		TableItem[] iteMs = ArchiveTable.getItems();
		
		for (int i = 0; i<=ArchiveTable.getItemCount() -1; i++)
		{
			for (int j = 0; j<=3; j++)
			{
				A_ArchiveTable[i][j] = iteMs[i].getText(j); 
				StringArchiveTable += iteMs[i].getText(j) + ";"; 
			}
			StringArchiveTable = StringArchiveTable.substring(0, StringArchiveTable.length()-1);
			StringArchiveTable = StringArchiveTable + "-";
		}
		StringArchiveTable = StringArchiveTable.substring(0, StringArchiveTable.length()-1);
	}

	public void getData()
	{
			Text0.setText(Const.NVL(input.getRRDFilename(), ""));
			Text1.setText(Const.NVL(input.getRRDDatasource(), ""));
			combo.setText(Const.NVL(input.getRRDType(), ""));
			Text3.setText(Const.NVL(input.getRRDHeartBeat(), ""));
			Text10.setText(Const.NVL(input.getRRDStartTime(), ""));
			Text4.setText(Const.NVL(input.getRRDMini(), ""));
			Text5.setText(Const.NVL(input.getRRDMaxi(), ""));
			combo1.setText(Const.NVL(input.getRRDFType(), ""));
			combo2.setText(Const.NVL(input.getRRDXFile(), ""));
			Text8.setText(Const.NVL(input.getRRDNBSteps(), ""));
			Text9.setText(Const.NVL(input.getRRDNBRows(), ""));
			WriteComboValues(Const.NVL(input.getRRDArchives(), ""));

			wStepname.selectAll();
	}
	
	private void WriteComboValues(String TB) //TB = long chain to split and load into combo
	{
		// if no values, we don't try to fill the combo
		if (TB == "") return;
			
		ArchiveTable.removeAll();
		String[] dd = TB.split("-");
		String[][] element = new String[dd.length][4];
		{
			for (int i=0;i<=dd.length-1;i++)
			{
			element[i] = dd[i].split(";"); // you have a 2dim array here !!!
			item = new TableItem(ArchiveTable, SWT.NONE);
			item.setText(new String[] {element[i][0], element[i][1], element[i][2], element[i][3]});
			}
		}
	}
	
	private void cancel()
	{
		stepname=null;
		input.setChanged(changed);
		dispose();
	}
	
	private void ok()
	{
		//First, we check if a RRD file has been created
		// If not created, a warning is sent.
		boolean exists = (new File(Text0.getText().toString())).exists();
		if (!exists) {
			MessageBox messageBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
		    messageBox.setText("Warning");
		    messageBox.setMessage("You didn't really create the RRD file [" + Text0.getText().toString() + "]. Please, use button Validate and Create before starting your transformation." );
		    messageBox.open();
		}
		stepname = wStepname.getText(); // return value
	    input.setRRDFilename(Text0.getText());
		input.setRRDDatasource(Text1.getText());
		input.setRRDType(combo.getText());
		input.setRRDHeartBeat(Text3.getText());
		input.setRRDStartTime(Text10.getText());
		input.setRRDMini(Text4.getText());
		input.setRRDMaxi(Text5.getText());
		input.setRRDFType(combo1.getText());
		input.setRRDXFile(combo2.getText());
		input.setRRDNBSteps(Text8.getText());
		input.setRRDNBRows(Text9.getText());
		BuildArchive();
		input.setRRDArchives(StringArchiveTable);

		dispose();
	}

	public String CreateRRDFile(String RRDFile, long RRDStartDB, String DSName, String DSType, Long HeartBt, double MinVal, double MaxVal  ) throws RrdException, IOException{
		// Create file
		rrdDef = new RrdDef(RRDFile);
		rrdDef.setStartTime(RRDStartDB);
		rrdDef.addDatasource(DSName, DSType, HeartBt, MinVal, MaxVal);
		for (int i=0;i<=A_ArchiveTable.length-1;i++)
		{
			rrdDef.addArchive(A_ArchiveTable[i][0], Double.parseDouble(A_ArchiveTable[i][1]), Integer.parseInt(A_ArchiveTable[i][2]), Integer.parseInt(A_ArchiveTable[i][3]));
		}
		try
		{
			RrdDb rrdDb = new RrdDb(rrdDef);
			String[] DsNames = rrdDb.getDsNames();
			return (DsNames[0]);
		} catch (RrdException e1) {
			return e1.toString();
		}
	}
	
}
